#include "selectionrect.h"
#include "drawingarea.h"

using namespace std;

//************************************************************* Constructor

SelectionRect::SelectionRect(DrawingArea* drawingAreaUse, QDockWidget* dockInfoToolParam) :Selection(drawingAreaUse){
    dockInfoTool = dockInfoToolParam;
    infoOutilSelection(0,0,0,0);
    drawingArea = drawingAreaUse;
}

//************************************************************* Affichage of Dock Tool Info

void SelectionRect::infoOutilSelection(int xBegin, int yBegin,int xEnd, int yEnd){
    QWidget* widgetInfoToolUp = new QWidget();
    QWidget* widgetInfoTool = new QWidget(widgetInfoToolUp);
    QGridLayout* layoutInfoTool = new QGridLayout();

    buttonValidTailleRect = new QPushButton();
    QLabel *labelInfoGenTool = new QLabel();
    QLabel *labelInfoHautGauche = new QLabel();
    labelPointHautGauche = new QLabel();
    QLabel *labelInfoTailleRectangle = new QLabel();
    labelTailleRectangle = new QLabel();
    spinXBegin = new QSpinBox();
    spinXEnd = new QSpinBox();
    spinYBegin = new QSpinBox();
    spinYEnd= new QSpinBox();

    buttonValidTailleRect->setText("OK");
    labelInfoGenTool->setText(QString::fromUtf8("Rectangle de sélection : "));
    labelInfoHautGauche->setText(QString::fromUtf8("Sélection haut gauche :"));
    QString convert;
    QString convert1;
    QString convert2;
    QString convert3;
    labelPointHautGauche->setText(convert.setNum(xBegin)+"x"+convert1.setNum(yBegin));
    labelInfoTailleRectangle->setText(QString::fromUtf8("Taille du rectangle :"));
    int tailleRectX = xEnd-xBegin;
    int tailleRectY = yEnd-yBegin;
    labelTailleRectangle->setText(convert2.setNum(tailleRectX)+"x"+convert3.setNum(tailleRectY));

    spinXBegin->setMaximum(100000);
    spinXEnd->setMaximum(100000);
    spinYBegin->setMaximum(100000);
    spinYEnd->setMaximum(100000);

    spinXBegin->setValue(xBegin);
    spinXEnd->setValue(xEnd);
    spinYBegin->setValue(yBegin);
    spinYEnd->setValue(yEnd);

    QLabel *labelXBegin = new QLabel();
    QLabel *labelXEnd = new QLabel();
    QLabel *labelYBegin = new QLabel();
    QLabel *labelYEnd = new QLabel();
    labelXBegin->setText("XBegin :");
    labelXEnd->setText("XEnd :");
    labelYBegin->setText("YBegin :");
    labelYEnd->setText("YEnd :");

    layoutInfoTool->addWidget(labelInfoGenTool, 0, 0, Qt::AlignVCenter);
    layoutInfoTool->addWidget(labelInfoHautGauche, 0, 1, Qt::AlignVCenter);
    layoutInfoTool->addWidget(labelPointHautGauche, 0, 2, Qt::AlignVCenter);
    layoutInfoTool->addWidget(labelInfoTailleRectangle, 0, 3, Qt::AlignVCenter);
    layoutInfoTool->addWidget(labelTailleRectangle, 0, 4, Qt::AlignVCenter);
    layoutInfoTool->addWidget(labelXBegin, 0, 5, Qt::AlignVCenter);
    layoutInfoTool->addWidget(spinXBegin, 0, 6, Qt::AlignVCenter);
    layoutInfoTool->addWidget(labelXEnd, 0, 7, Qt::AlignVCenter);
    layoutInfoTool->addWidget(spinXEnd, 0, 8, Qt::AlignVCenter);
    layoutInfoTool->addWidget(labelYBegin, 0, 9, Qt::AlignVCenter);
    layoutInfoTool->addWidget(spinYBegin, 0, 10, Qt::AlignVCenter);
    layoutInfoTool->addWidget(labelYEnd, 0, 11, Qt::AlignVCenter);
    layoutInfoTool->addWidget(spinYEnd, 0, 12, Qt::AlignVCenter);
    layoutInfoTool->addWidget(buttonValidTailleRect, 0, 13, Qt::AlignVCenter);
    widgetInfoTool->setLayout(layoutInfoTool);
    dockInfoTool->setWidget(widgetInfoToolUp);
    QObject::connect(buttonValidTailleRect,SIGNAL(pressed()),this,SLOT(changePositionRect()));
}

void SelectionRect::changePositionRect(){
    xBegin = spinXBegin->value();
    yBegin = spinYBegin->value();
    xEnd = spinXEnd->value();
    yEnd = spinYEnd->value();

    endSelectionRect(spinXEnd->value(),spinYEnd->value());
    drawingArea->update();
}


//************************************************************* SelectionRect movement

void SelectionRect::beginSelectionRect(int x, int y){
    xBegin = x;
    yBegin = y;
    xEnd = x;
    yEnd = y;
    isDrawingSelection = true;
    isSelectionEmpty = true;
    isDeselectionned = false;
    infoOutilSelection(xBegin,yBegin,xEnd,yEnd);
}

void SelectionRect::selectionningRect(int x, int y){
    xEnd = x;
    yEnd = y;
    infoOutilSelection(xBegin,yBegin,xEnd,yEnd);
}

void SelectionRect::endSelectionRect(int x, int y){
    // If the begin of the selection is equal to the end then that mean that
    // the user want to deselection
    if(x == xBegin && y == yBegin){
        isDeselectionned = true;
        return;
    }
    // Area that the user want
    if(x < xBegin){
        xEnd = xBegin;
        xBegin = x;
    }else{
        xEnd = x;
    }
    if(y < yBegin){
        yEnd = yBegin;
        yBegin = y;
    }else{
        yEnd = y;
    }

    // Area that is possible in accordance with the position and size of current layer
    Layer* layerSelected = drawingArea->getCurrentLayer();
    realBeginX = max(xBegin, (int) layerSelected->pos().x());
    realBeginY = max(yBegin, (int) layerSelected->pos().y());
    realEndX = min(xEnd, layerSelected->getWidth() + (int) layerSelected->pos().x());
    realEndY = min(yEnd, layerSelected->getHeight() + (int) layerSelected->pos().y());

    if(((realEndX - realBeginX) <= 0) || ((realEndY - realBeginY) <= 0)){
        isSelectionEmpty = true;
    }else{
        isSelectionEmpty = false;
    }
    infoOutilSelection(xBegin,yBegin,xEnd,yEnd);
    isDrawingSelection = false;

    drawingArea->XBeginSelection = realBeginX;
    drawingArea->XEndSelection = realEndX;
    drawingArea->YBeginSelection = realBeginY;
    drawingArea->YEndSelection= realEndY;
}

//************************************************************* Paint

void SelectionRect::paint(QPainter *painter,const QStyleOptionGraphicsItem *option,QWidget *widget){
    if(isDeselectionned){
        return;
    }

    if(isDrawingSelection){
        painter->setPen(QColor(0, 0, 0));
        painter->drawRect(xBegin, yBegin, xEnd - xBegin, yEnd - yBegin);
    }else{
        if(isSelectionEmpty){
            painter->setPen(QColor(255, 255, 255));
            painter->drawRect(xBegin, yBegin, xEnd - xBegin, yEnd - yBegin);
            QPen pen(QColor(255, 0, 0));
            pen.setStyle(Qt::DashLine);
            pen.setDashOffset (0);
            QVector<qreal> dashes;
            qreal space = 8;
            dashes << 8 << space;
            pen.setDashPattern(dashes);
            painter->setPen(pen);
            painter->drawRect(xBegin, yBegin, xEnd - xBegin, yEnd - yBegin);
        }else{
            painter->setPen(QColor(255, 255, 255));
            painter->drawRect(xBegin, yBegin, xEnd - xBegin, yEnd - yBegin);
            QPen pen(QColor(0, 0, 0));
            pen.setStyle(Qt::DashLine);
            pen.setDashOffset (0);
            QVector<qreal> dashes;
            qreal space = 8;
            dashes << 8 << space;
            pen.setDashPattern(dashes);
            painter->setPen(pen);

            painter->drawRect(xBegin, yBegin, xEnd - xBegin, yEnd - yBegin);
        }
    }
}

Layer* SelectionRect::imageSelected(Layer* layer, int posX, int posY){
    realBeginX = max(xBegin, (int) layer->pos().x());
    realBeginY = max(yBegin, (int) layer->pos().y());
    realEndX = min(xEnd,layer->getWidth() + (int) layer->pos().x());
    realEndY = min(yEnd,layer->getHeight() + (int) layer->pos().y());

    if(realEndX -realBeginX <= 0 || realEndY - realBeginY <= 0){
        isSelectionEmpty = true;
    }else{
        isSelectionEmpty = false;
    }

    if(isSelectionEmpty || isDeselectionned){
        return NULL;
    }
    // Creation of the layer representing the area selectionned
    Layer* imageSelected = new Layer(posX, posY, realEndX- realBeginX,realEndY - realBeginY);
    imageSelected->setSizeBoundingRect(drawingArea->getWidth(),drawingArea->getHeight());

    int posXSource = realBeginX - posX;
    int posYSource = realBeginY - posY;

    int x = 0;
    int y = 0;

    for(int i = posXSource; i < realEndX - posX; i++){
        y = 0;
        for(int j = posYSource; j < realEndY - posY; j++){
            QRgb rgb = layer->getImage()->pixel(i, j);
            imageSelected->getImage()->setPixel(x, y, rgb);
            y++;
        }
        x++;
    }
    return imageSelected;
}

void SelectionRect::refresh(){
    // Area that is possible in accordance with the position and size of current layer
    Layer* layerSelected = drawingArea->getCurrentLayer();
    realBeginX = max(xBegin, (int) layerSelected->pos().x());
    realBeginY = max(yBegin, (int) layerSelected->pos().y());
    realEndX = min(xEnd,
                   layerSelected->getWidth() + (int) layerSelected->pos().x());
    realEndY = min(yEnd,
                   layerSelected->getHeight() + (int) layerSelected->pos().y());

    if(realEndX -realBeginX <= 0 || realEndY - realBeginY <= 0){
        isSelectionEmpty = true;
    }else{
        isSelectionEmpty = false;
    }
}
